package com.lfy.ch06;


/**
 * 死锁场景：
 *      面试官：你给我说个死锁的例子，我就给你发offer
 *      我：你先给我发offer，我再给你说例子
 *
 * 发生死锁以后：排查一下：
 * 1、jps： 查询正在运行中的 Java 进程。拿到进程id
 * 2、jstack pid： 查看某个进程的线程快照(线程当时怎么执行的)
 *
 * 内容：
 * 1、new Thread()， 资源类操作和线程分开
 * 2、synchronized 锁对象， 判断锁对象是否同一个
 *
 * 小练习：
 *    1.两个线程交替执行（A线程干完活，自己停下，让B线程去干，B干完又让A干往复循环）：1个打印数字，1个打印字母
 *      1A2B3C4D5E6F7G8H9I
 *      机制：
 *      1、不轮到A干活A就等待，等到别人唤醒他？
 *      2、B干完活唤醒A，B就等待。
 *      3、A干完活唤醒B，A就等待。
 *
 */
public class DeadLockDemo {

    private Object lockA = new Object();
    private  Object lockB = new Object();
     int value;
    int another;

    public void add(int m) {
        synchronized(lockA) { // 获得lockA的锁
            this.value += m;
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            synchronized(lockB) { // 获得lockB的锁
                this.another += m;
            } // 释放lockB的锁
        } // 释放lockA的锁
    }

    public void dec(int m) {
        synchronized(lockB) { // 获得lockB的锁
            this.another -= m;
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            synchronized(lockA) { // 获得lockA的锁
                this.value -= m;
            } // 释放lockA的锁
        } // 释放lockB的锁
    }

    public static void main(String[] args) {
        DeadLockDemo demo = new DeadLockDemo();

        new Thread(()->{
            demo.add(1);
        }).start();


        new Thread(()->{
            demo.dec(2);
        }).start(); // 就绪 ==》 运行
    }
}
